package com.hxy.impl;

import com.hxy.enrity.Product;
import com.hxy.service.ProductService;
import com.hxy.vo.KeyValue;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.util.CollectionUtils;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.ParsedDoubleTerms;
import org.elasticsearch.search.aggregations.bucket.terms.ParsedStringTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.ParsedAvg;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.IndexOperations;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class ProductServiceImpl implements ProductService {

    @Autowired
    private ElasticsearchRestTemplate esTemplate;
    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @Override
    public Boolean createIndex() {
        IndexOperations ops = esTemplate.indexOps(Product.class);
        boolean exists = ops.exists();
        if (exists){
            return true;
        }
        return ops.create();
    }

    @Override
    public void insertDocument() {
        List<Product> list = new ArrayList<>();
        Product iphoneX = Product.builder().id(1).title("IphoneX").type("手机").price(5999.00).createTime(new Date()).description("苹果手机第十代").build();
        list.add(iphoneX);
        Product mac = Product.builder().id(2).title("MAC").type("电脑").price(10999.00).createTime(new Date()).description("最新款苹果电脑").build();
        list.add(mac);
        Product changHong = Product.builder().id(3).title("ChangHong").type("显示器").price(699.00).createTime(new Date()).description("性价比极高的电脑显示器").build();
        list.add(changHong);
        Product aoc = Product.builder().id(4).title("AOC").type("显示器").price(1099.00).createTime(new Date()).description("宝岛台湾知名品牌").build();
        list.add(aoc);
        Product huawei10 = Product.builder().id(5).title("HuaWeiMate30").type("手机").price(6999.00).createTime(new Date()).description("华为高端手机").build();
        list.add(huawei10);
        Product xiaomi = Product.builder().id(6).title("XiaoMi12").type("手机").price(999.00).createTime(new Date()).description("徕卡影像").build();
        list.add(xiaomi);
        Product oppo = Product.builder().id(7).title("OPPOReno").type("手机").price(2999.00).createTime(new Date()).description("照亮你的美").build();
        list.add(oppo);
        Product vivo = Product.builder().id(8).title("VIVO").type("手机").price(2999.00).createTime(new Date()).description("蓝厂的牌面").build();
        list.add(vivo);
        Product meizu = Product.builder().id(9).title("MeiZu18").type("手机").price(3999.00).createTime(new Date()).description("吉利太魅").build();
        list.add(meizu);
        Product huaweiIv = Product.builder().id(10).title("HuaWeiS+").type("显示器").price(1999.00).createTime(new Date()).description("全系4K显示").build();
        list.add(huaweiIv);
        Product rog = Product.builder().id(11).title("ROG").type("显示器").price(12999.00).createTime(new Date()).description("玩家国度SSS+").build();
        list.add(rog);
        esTemplate.save(list);
    }

    @Override
    public List<KeyValue> aggByType() {
        List<KeyValue> list = new ArrayList<>();
        SearchRequest request = new SearchRequest("product");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        TermsAggregationBuilder type = AggregationBuilders.terms("type.group").field("type.keyword");
        sourceBuilder
                .query(QueryBuilders.matchAllQuery())
                .aggregation(type)//设置聚合处理
                .size(0);
        request.source(sourceBuilder);
        try {
            SearchResponse searchResponse = restHighLevelClient.search(request, RequestOptions.DEFAULT);
            //处理聚合结果
            Aggregations aggregations = searchResponse.getAggregations();
            // 这里的强壮类型看情况，因为type是String：ParsedStringTerms
            //ParsedDoubleTerms 等等
            ParsedStringTerms aggregation = aggregations.get("type.group");
            List<? extends Terms.Bucket> buckets = aggregation.getBuckets();
            for (Terms.Bucket bucket : buckets) {
                list.add(new KeyValue(bucket.getKeyAsString(),String.valueOf(bucket.getDocCount())));
            }
            return list;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new ArrayList<>();
    }

    /**
     * max(ParsedMax)\min(ParsedMin)\sum(ParsedSum)\avg(ParsedAvg) 聚合函数
     */
    @Override
    public List<KeyValue> avgAggByType() {
        List<KeyValue> list = new ArrayList<>();
        SearchRequest request = new SearchRequest("product");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //根据类型分组
        TermsAggregationBuilder type = AggregationBuilders.terms("type.group").field("type.keyword");
        //求不同类型的平均价格
        type.subAggregation(AggregationBuilders.avg("price_avg").field("price"));
        sourceBuilder
                .query(QueryBuilders.matchAllQuery())
                .aggregation(type)//设置聚合处理
                .size(0);
        request.source(sourceBuilder);
        try {
            SearchResponse searchResponse = restHighLevelClient.search(request, RequestOptions.DEFAULT);
            ParsedStringTerms aggregation = searchResponse.getAggregations().get("type.group");
            for (Terms.Bucket bucket : aggregation.getBuckets()) {
                ParsedAvg avg = bucket.getAggregations().get("price_avg");
                list.add(new KeyValue("类型是："+bucket.getKeyAsString(),",数量是："+bucket.getDocCount()+",平均价格是："+avg.getValue()));
                return list;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new ArrayList<>();
    }
}
